﻿using AutoMapper;
using IOA.MES.DataAccess.Entity;
using IOA.MES.DataAccess.VModel;
using System;
using System.Collections.Generic;
using System.Linq;
using IOA.MES.Common;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity.Core.Objects.DataClasses;

namespace IOA.MES.Business
{
    /// <summary>
    /// 部门管理（错误代码：126001）
    /// </summary>
    public class DepartmentMgr
    {
        private MESContext mesDb = new MESContext("MES");

        /// <summary>
        /// 查询部门列表
        /// </summary>
        /// <param name="parentId">父级ID</param>
        /// <returns>部门列表</returns>
        public List<VDepartment> QueryDepartments(int? parentId = null)
        {
            List<Department> entities = new List<Department>();
            if (parentId.HasValue)
            {
                entities.AddRange(mesDb.Departments.Where(_ => _.PkId > 1 && _.ParentId == parentId.Value && _.Valid).ToList());
            }
            else
            {
                entities.AddRange(mesDb.Departments.Where(_ => _.PkId > 1 && _.Valid).ToList());
            }

            entities = entities.OrderBy(_ => _.ParentId).ThenBy(_ => _.PkId).ToList();

            return Mapper.Map<List<VDepartment>>(entities);
        }

        /// <summary>
        /// 查询部门列表
        /// </summary>
        /// <param name="parentId">父级ID</param>
        /// <returns>部门列表</returns>
        public List<VDepartment> QueryUserDepartments(int userId = 0)
        {
            var userRoles = (from u in mesDb.Users.AsNoTracking()
                             join ur in mesDb.UserRoles.AsNoTracking() on u.PkId equals ur.UserId
                             join r in mesDb.Roles.AsNoTracking() on ur.RoleId equals r.PkId
                             where u.Valid && u.PkId == userId && ur.Valid && r.Valid && r.IsManager
                             select r).ToList();
            if (!userRoles.Any())
            {
                return new List<VDepartment>();
            }

            var allDepartments = mesDb.Departments.AsNoTracking().Where(_ => _.PkId != 1 && _.Valid).ToList();
            if (userRoles.Any(_ => _.PkId == 1))
            {
                return Mapper.Map<List<VDepartment>>(allDepartments);
            }

            var departments = new List<Department>();
            foreach (var role in userRoles)
            {
                var roleDepartment = allDepartments.FirstOrDefault(_ => _.PkId == role.DepartmentId);
                if (roleDepartment != null)
                {
                    departments.Add(roleDepartment);
                    departments.AddRange(getSubDepartments(allDepartments, roleDepartment.PkId));
                }
            }

            var models = Mapper.Map<List<VDepartment>>(departments.OrderBy(_ => _.ParentId).ThenBy(_ => _.PkId).ToList());
            if (models.Any())
            {
                var allRoles = mesDb.Roles.AsNoTracking().Where(_ => _.Valid).ToList();
                models.ForEach(model =>
                {
                    model.Roles.AddRange(Mapper.Map<List<VRole>>(allRoles.Where(_ => _.DepartmentId == model.PkId).ToList()));
                });
            }

            return models;
        }
        private List<Department> getSubDepartments(List<Department> allDepartments, int parentId)
        {
            var departments = new List<Department>();
            var children = allDepartments.Where(_ => _.ParentId == parentId).ToList();
            departments.AddRange(children);
            foreach (var department in children)
            {
                departments.AddRange(getSubDepartments(allDepartments, department.PkId));
            }
            return departments;
        }

        /// <summary>
        /// 查询子部门列表
        /// </summary>
        /// <param name="parentId">父级ID</param>
        /// <param name="containsParent">是否包含本身</param>
        /// <returns>子部门列表</returns>
        public List<VDepartment> QuerySubDepartments(int parentId, bool containsParent = false)
        {
            if (parentId <= 0)
            {
                return new List<VDepartment>();
            }

            var allDepartments = mesDb.Departments.AsNoTracking().Where(_ => _.PkId != 1 && _.Valid).ToList();
            var parentDepartment = allDepartments.FirstOrDefault(_ => _.PkId == parentId && _.Valid);
            if (parentDepartment == null)
            {
                return new List<VDepartment>();
            }

            var departments = new List<Department>();
            if (containsParent)
            {
                departments.Add(parentDepartment);
            }
            foreach (var department in allDepartments.Where(_ => _.ParentId == parentId).ToList())
            {
                departments.Add(department);
                departments.AddRange(getSubDepartments(allDepartments, department.PkId));
            }

            departments = departments.OrderBy(_ => _.ParentId).ThenBy(_ => _.PkId).ToList();

            return Mapper.Map<List<VDepartment>>(departments);
        }

        /// <summary>
        /// 编辑部门
        /// </summary>
        /// <param name="model">部门对象</param>
        /// <returns>编辑后的部门</returns>
        public VDepartment EditDepartment(VDepartment model)
        {
            var userDepartments = QueryUserDepartments(model.PkId <= 0 ? model.CreateBy : model.ModifyBy);
            if (model.ParentId == 0)
            {
                var user = new UserMgr().GetUser(model.PkId <= 0 ? model.CreateBy : model.ModifyBy);
                if (model.PkId <= 0)
                {
                    if (user == null || !user.Roles.Any(_ => _.PkId == 1))
                    {
                        throw new MultiLanBizException(126004);//只有超级管理员可以添加一级部门
                    }
                }
                else
                {
                    if ((user == null || !user.Roles.Any(_ => _.PkId != 1)) && !userDepartments.Any(_ => _.PkId == model.PkId))
                    {
                        throw new MultiLanBizException(126008);//您没有管理当前部门的权限
                    }
                }
            }

            if (model.PkId <= 0)
            {
                var exist = mesDb.Departments.FirstOrDefault(_ => _.DepartmentName == model.DepartmentName && _.Valid);
                if (exist != null)
                {
                    throw new MultiLanBizException(126001);// "部门名称已存在，请更换其他名称");
                }
                else if (model.ParentId > 0 && !userDepartments.Any(_ => _.PkId == model.ParentId))
                {
                    throw new MultiLanBizException(126008);//您没有管理当前部门的权限
                }

                model.CreateTime = DateTime.Now;
                model.ModifyBy = 0;
                var entity = Mapper.Map<Department>(model);
                mesDb.Departments.Add(entity);
                mesDb.SaveChanges();

                model = Mapper.Map<VDepartment>(entity);
            }
            else
            {
                var exist = mesDb.Departments.FirstOrDefault(_ => _.DepartmentName == model.DepartmentName && _.PkId != model.PkId && _.Valid);
                if (exist != null)
                {
                    throw new MultiLanBizException(126001);// "部门名称已存在，请更换其他名称");
                }
                var entity = mesDb.Departments.AsNoTracking().FirstOrDefault(_ => _.PkId == model.PkId && _.Valid);
                if (entity == null)
                {
                    throw new MultiLanBizException(126002);// "部门不存在或已被删除，无法编辑");
                }
                else if (!userDepartments.Any(_ => _.PkId == model.PkId))
                {
                    throw new MultiLanBizException(126008);//您没有管理当前部门的权限
                }
                mesDb.Departments.Attach(entity);
                entity.DepartmentName = model.DepartmentName;
                entity.ModifyBy = model.ModifyBy;
                entity.ModifyTime = DateTime.Now;
                mesDb.SaveChanges();

                model = Mapper.Map<VDepartment>(entity);
            }

            return model;
        }

        /// <summary>
        /// 删除部门
        /// </summary>
        /// <param name="model">部门对象</param>
        public void DeleteDepartment(VDepartment model)
        {
            var allDepartments = Mapper.Map<List<Department>>(QueryUserDepartments(model.ModifyBy));
            var entity = allDepartments.FirstOrDefault(_ => _.PkId == model.PkId && _.Valid);
            if (entity == null)
            {
                throw new MultiLanBizException(126003);//部门不存在或已被删除，无法再次删除
            }
            else if (entity.ParentId == 0)
            {
                var user = new UserMgr().GetUser(model.ModifyBy);
                if (user == null || !user.Roles.Any(_ => _.PkId == 1))
                {
                    throw new MultiLanBizException(126005);//只有超级管理员可以删除一级岗位
                }
            }

            var departments = getSubDepartments(allDepartments, entity.PkId);
            departments.Add(entity);
            var departmentIds = departments.Select(_ => _.PkId).ToList();
            var roles = (from r in mesDb.Roles.AsNoTracking()
                         where r.Valid && r.DepartmentId == model.PkId
                         select r).ToList();
            if (roles.Any())
            {
                throw new MultiLanBizException(126006);// 请先将该部门及其所有子部门的岗位删除
            }

            mesDb.Departments.Attach(entity);
            entity.Valid = false;
            entity.ModifyBy = model.ModifyBy;
            entity.ModifyTime = DateTime.Now;
            mesDb.SaveChanges();
        }

        /// <summary>
        /// 查询用户部门角色
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns>部门角色</returns>
        //public List<VDepartment> QueryUserDepartments(int userId)
        //{
        //    var userRoles = (from userRole in mesDb.UserRoles.Where(_ => _.UserId == userId && _.Valid)
        //                     join role in mesDb.Roles.Where(_ => _.Valid) on userRole.RoleId equals role.PkId
        //                     select role).ToList();

        //    var query = mesDb.Departments.Where(_ => _.Valid);
        //    if (!userRoles.Any(_ => new[] { 1, 2 }.Contains(_.PkId)))
        //    {
        //        query = from department in query
        //                join userRole in mesDb.UserRoles.Where(_ => _.UserId == userId && _.Valid) on department.PkId equals userRole.DepartmentId
        //                select department;
        //    }
        //    var entities = query.Distinct().OrderBy(_ => _.DepartmentName).ToList();
        //    var models = Mapper.Map<List<VDepartment>>(entities);

        //    var departmentIds = models.Select(_ => _.PkId).ToList();
        //    var roles = Mapper.Map<List<VRole>>(mesDb.Roles.Where(_ => departmentIds.Contains(_.DepartmentId) && _.Valid).OrderBy(_ => _.PkId).ToList());

        //    models.ForEach(department =>
        //    {
        //        department.Roles = roles.Where(_ => _.DepartmentId == department.PkId).ToList();
        //    });

        //    return models;
        //}
    }
}
